#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "../header/wordAnalysis.h"
void init()
{
	/*
	 initialize the symbol of the reserved word
	 */
	wsym[0] = AUTOSYM;
	wsym[1] = BREAKSYM;
	wsym[2] = CASESYM;
	wsym[3] = CHARSYM;
	wsym[4] = CONSTSYM;
	wsym[5] = CONTINUESYM;
	wsym[6] = DEFAULTSYM;
	wsym[7] = DOSYM;
	wsym[8] = DOUBLESYM;
	wsym[9] = ELSESYM;
	wsym[10] = ENUMSYM;
	wsym[11] = EXTERNSYM;
	wsym[12] = FLOATSYM;
	wsym[13] = FORSYM;
	wsym[14] = GOTOSYM;
	wsym[15] = IFSYM;
	wsym[16] = INTSYM;
	wsym[17] = LONGSYM;
	wsym[18] = REGISTERSYM;
	wsym[19] = RETURNSYM;
	wsym[20] = SHORTSYM;
	wsym[21] = SIGNEDSYM;
	wsym[22] = SIZEOFSYM;
	wsym[23] = STATICSYM;
	wsym[24] = STRUCTSYM;
	wsym[25] = SWITCHSYM;
	wsym[26] = TYPEDEFSYM;
	wsym[27] = UNIONSYM;
	wsym[28] = UNSIGNEDSYM;
	wsym[29] = VOIDSYM;
	wsym[30] = VOLATILESYM;
	wsym[31] = WHILESYM;
	/*

	 ��ʼ�����Ĵ��

	 */
	dsym[0] = COMMA;
	dsym[1] = SEMICOLON;
	dsym[2] = LBRACKET;
	dsym[3] = RBRACKET;
	dsym[4] = LBRACE;
	dsym[5] = RBRACE;

	/*
	 initialize the name of the reserved word
	 */
	keyword[0] = "auto";
	keyword[1] = "break";
	keyword[2] = "case";
	keyword[3] = "char";
	keyword[4] = "const";
	keyword[5] = "continue";
	keyword[6] = "default";
	keyword[7] = "do";
	keyword[8] = "double";
	keyword[9] = "else";
	keyword[10] = "enum";
	keyword[11] = "extern";
	keyword[12] = "float";
	keyword[13] = "for";
	keyword[14] = "goto";
	keyword[15] = "if";
	keyword[16] = "int";
	keyword[17] = "long";
	keyword[18] = "register";
	keyword[19] = "return";
	keyword[20] = "short";
	keyword[21] = "signed";
	keyword[22] = "sizeof";
	keyword[23] = "static";
	keyword[24] = "struct";
	keyword[25] = "switch";
	keyword[26] = "typedef";
	keyword[27] = "union";
	keyword[28] = "unsigned";
	keyword[29] = "void";
	keyword[30] = "volatile";
	keyword[31] = "while";
	/*init the delimeter*/
	delimeter[0] = ',';
	delimeter[1] = ';';
	delimeter[2] = '(';
	delimeter[3] = ')';
	delimeter[4] = '{';
	delimeter[5] = '}';

	fpin = stdin;
	fpout = stdout;
}
/*
return the index of ch if it is the key word,or return -1
 */
int findKeyWord()
{
	int low = 0, high = WORDS_SIZE - 1;
	int middle;
	while ( low <= high )
	{
		middle = (low + high) / 2;
		if ( strcmp( keyword[middle], id ) == 0 )
			return middle;
		else if ( strcmp( keyword[middle], id ) > 0 )
			high = middle - 1;
		else
			low = middle + 1;
	}
	return -1;
}

int findDelimeter( char a )
{
	int i;
	for ( i = 0; i < DIVIDESY_SIZE; i++ )
	{
		if ( a == delimeter[i] )
			return i;
	}
	return -1;
}
int calc( char * a )
{
	char * t;
	int result = 0;
	t = a;
	while ( *t != '\0' )
	{

		result = 10* result + *t++ - '0';
	}
	return result;
}
int getch()
{
	ch = fgetc( fpin );
	return ch;
}
void dealIdent()
{
	int k = 0, j;
	char a[MAX_IDEN_LEN + 1];
	do
	{
		if ( k < MAX_IDEN_LEN )
		{
			a[k++] = ch;
		}
		getch();
	} while ( isalnum(ch) || ch == '_' );
	a[k] = '\0';
	strcpy( id, a );
	if ( (j = findKeyWord()) == -1 )
	{
		sym = IDENT;
	}
	else
	{
		sym = wsym[j];
	}
}
void dealNum()
{
	int k = 0;
	char a[MAX_NUM_SIZE + 1];
	do
	{
		if ( k < MAX_NUM_SIZE )
		{
			a[k++] = ch;
		}
		getch();
	} while ( isdigit(ch) || ch == '.' );
	a[k] = '\0';
	strcpy( number, a );
	sym = NUMBER;
}

void dealError(errornum e)
{
	fclose(fpout);
	fpout = fopen("out.txt", "w");
	fprintf(fpout,"Error%d:",e);
	switch(e)
	{
		case 0:
			fprintf(fpout,"缺少“\"”\n");
			break;
		case 1:
			fprintf(fpout,"缺少“'”\n");
			break;
	}
}
void dealString()
{
	char c;
	int k = 0;
	char a[MAX_NUM_SIZE + 1];
	while((c = getch()) != '\"')
	{
		if(c == ';')
		{
			dealError(0);
		}
		else
		{
			a[k++] = ch;
		}
	}
	a[k] = '\0';
	sym = CONSTSTRING;
	strcpy( id, a );
	getch();
}
void getSym()
{
	int i = 0;
	char c;
	id[0] = '\0';
	number[0] = '\0';
	sym = UNKNOWN;
	while ( isspace(ch)|| ch == '\n')
	{
		getch();
	}
	if ( isalpha(ch) || ch == '_' )
	{
		dealIdent();
	}
	else if ( isdigit(ch) )
	{
		dealNum();
	}
	else if ( (i = findDelimeter( ch )) >= 0 )
	{
		sym = dsym[i];
		id[0] = ch;
		id[1] = '\0';
		getch();
	}
	else
	{
		i = 0;
		id[i++] = ch;
		switch ( ch )
		{
			case '>':
				sym = GREATER;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = GEQUAL;
					getch();
				}
				id[i++] = '\0';

				break;
			case '<':
				sym = LESS;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = LEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '=':
				sym = EVALUATE;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = EQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '!':
				sym = NOT;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = NEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '+':
				sym = PLUS;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = PLUSEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;

			case '-':
				sym = MINUS;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = MINUSEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '*':
				sym = MULTIPLY;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = MULEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '/':
				sym = DIVIDE;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = DIVEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '%':
				sym = REMAIN;
				if ( getch() == '=' )
				{
					id[i++] = '=';
					sym = REMEQUAL;
					getch();
				}
				id[i++] = '\0';
				break;
			case '\'':
				c = getch();
				if (getch() == '\'' )
				{
						id[i-1] = c;
						sym = CONSTCHAR;
						getch();
				}
				else
				{
					dealError(1);
					exit(-1);
				}
				id[i++] = '\0';
				break;
			case '\"':
				id[i-1]='\0';
				dealString();
		}
	}
}

